import axios from 'axios'
import type {
  InternalAxiosRequestConfig,
  AxiosResponse,
  AxiosRequestConfig,
  AxiosInstance,
  AxiosRequestHeaders,
  AxiosError
} from 'axios'
import { ElMessage } from 'element-plus'
export const getToken = () => {
  return window.localStorage.getItem('token')
}

// 请求contentType
const CONTENT_TYPE = 'application/json'
// 请求超时时间
const REQUEST_TIMEOUT = 60000
// Token key
const TOKEN_KEY = 'Authorization'
// 请求成功状态码
const SUCCESS_CODE = 0
const PATH_URL = '/xxx'


const axiosInstance: AxiosInstance = axios.create({
  timeout: REQUEST_TIMEOUT,
  baseURL: PATH_URL
})


// axios拦截器--response
const defaultResponseInterceptors = (response: AxiosResponse) => {
  console.log('response', response)
  if (response?.config?.responseType === 'blob') {
    // 如果是文件流，直接过
    return response
  } else {
    const code = response?.data?.code
    if (code === SUCCESS_CODE) {
      return response.data
    } else {
      ElMessage.error(response?.data?.message)
      if (code === 401) {
        // const userStore = useUserStoreWithOut()
        // userStore.logout()
      }
    }
  }
}
axiosInstance.interceptors.response.use(defaultResponseInterceptors)



/**
 * Http 接口统一响应体
 */
export type HttpResult<T = any> = {
  code: number
  message: string
  data: T extends any ? T : T & any
}



/**
 * 创建请求
 * @param method        请求方法
 * @param url           接口当前
 * @param config        axios配置
 * @returns 
 */
const createRequest =  <T = any, P = any>(method: string, url: string, config: AxiosRequestConfig = {}): (req?: P) => Promise<HttpResult<T>> => {
  const paramKey = ['post', 'put', 'patch'].includes(method) ? 'data' : 'params'
  return (req?: P): Promise<HttpResult<T>> => {
    const { headers, responseType } = config
    return axiosInstance.request({
      url: url,
      method,
      [paramKey]: req || {},
      responseType: responseType,
      headers: {
        'Content-Type': CONTENT_TYPE,
        [TOKEN_KEY ?? 'Authorization']: getToken() ?? '',
        ...headers
      },
      ...config,
    })
  } 
}



export default {
  get: <P = any, T = any>(url: string, config?: AxiosRequestConfig): (req?: P) => Promise<HttpResult<T>> => {
    return createRequest<T, P>('get', url, config)
  },
  post: <P = any, T = any>(url: string, config?: AxiosRequestConfig): (req?: P) => Promise<HttpResult<T>> => {
    return createRequest<T, P>('post', url, config)
  },
  delete: <P = any, T = any>(url: string, config?: AxiosRequestConfig): (req?: P) => Promise<HttpResult<T>> => {
    return createRequest<T, P>('delete', url, config)
  },
  put: <P = any, T = any>(url: string, config?: AxiosRequestConfig): (req?: P) => Promise<HttpResult<T>> => {
    return createRequest<T, P>('put', url, config)
  },

}
